package com.project.ToDone;

import java.util.ArrayList;

import android.content.Context;
import android.view.View.OnClickListener;
import android.widget.Toast;

//import android.content.Context;

/**
 * The program that runs all program logic
 * 
 * 
 * @author Matthew Guzdial
 * @param <User>
 * @param <User>
 *
 */
class MasterControlProgram{
	private static User currUser;
	private static ArrayList<User> users = new ArrayList<User>();
	private static boolean newUser=false;
	private static Event newEvent;
	private static Event alteredEvent;
	private static Context savedContext;
	
	public static void instantiateEvents(){
		currUser.setToDoList(new ToDoList());
	}
	
	/**
	 * Creates a SQLDatabase class to read in the list of users,
	 * and sets MCP's list of users equal to it
	 * 
	 */
	public static void loadUsers(Context context){
		DatabaseHelper dH = new DatabaseHelper(context);
		ArrayList<User> usersList = dH.acquireUsers();
		if(usersList!=null){
			users=usersList;
		}
		else{
			users= new ArrayList<User>();
		}
	}
	
	/**
	 * Loads events based on currUser's username
	 * 
	 * @param context
	 */
	public static void loadEvents(Context context){
		
		DatabaseHelper dH = new DatabaseHelper(context);
		ArrayList<Event> events = dH.getEventsByUsername(currUser.getUsername());
		if(!events.isEmpty()){
			
			currUser.setToDoList(new ToDoList(events));
		}
		else{
			
			
			currUser.setToDoList(new ToDoList());
		}
		
	}
	
	public static void updateEvent(Context context, Event e){
		DatabaseHelper dH = new DatabaseHelper(context);

		dH.UpdateEvent(e, currUser);
	}
	
	/**
	 * Writes out whole list of users, should only be called
	 * when database has been wiped
	 * 
	 * @param context the "this" for whatever activity the method is called in
	 */
	public static void writeOutUsers(Context context){
		DatabaseHelper dH = new DatabaseHelper(context);
		dH.addUserList(users);
	}
	
	/**
	 * Adds a user to the database, should be called after register
	 * 
	 * @param context the "this" for whatever activity the method is called in
	 * @param user
	 */
	public static void addUserToDatabase(Context context, User user){
		DatabaseHelper dH = new DatabaseHelper(context);
		dH.addUser(user);
	}
	

		
	
	/**
	 * Method for logging in, checks it's list of users for each
	 * possibility
	 * 
	 * @param username
	 * @param password
	 * @return 0, all correct, 1 indicates wrong Username, 2 wrong Password, 3 wrong everything. 
	 */
	public static int login(String username, String password)
	{
		for(User u: users)
		{
			if(u.validate(username, password)==0)
			{
				currUser=u;
				//Tells display to display mainscreen (Set state to x)
				return 0;
			}
			else if(u.validate(username, password)==1)
			{
				//Tells display to display wrongUsernameLogIn (Set state to x)
				return 1;
			}
			else if(u.validate(username, password)==2){
				//Tells display to display wrongPasswordLogIn (Set state to x)
				return 2;
			}
		}
		
		//Tells display that such a user does not exist (Set state to x)
		return 3;
		
	}
	
	/**
	 * Logs out the current user
	 * 
	 */
	public static void logOut(){
		currUser=null;
	}
	
	
	
	/**
	 * Checks to see if a passed in username exists in the list (invalid) or does not (valid)
	 * 
	 * @param username potential new username
	 * @return false if invalid, true if valid
	 */
	public static boolean checkIfValid(String username){
		boolean answer = true;
		for(User u: users){
			
			if(u.getUsername().equals(username)){
				answer = false;
			}
		}
		return answer;
	}
	
	public static ArrayList<User> getUsers() {
		return users;
	}

	public static void setUsers(ArrayList<User> users) {
		MasterControlProgram.users = users;
	}

	/**
	 * Checks to see if a passed in password exists in the list (invalid) or does not (valid)
	 * 
	 * @param username potential new password
	 * @return false if invalid, true if valid
	 */
	public static boolean checkIfValidPassword(String password){
		boolean answer = true;
		for(User u: users){
			if(u.getPassword().equals(password)){
				answer = false;
			}
		}
		return answer;
	}
	
	public static void addEvent(Context context, Event e){
		if(currUser!=null){
			
			currUser.addEvent(e);
			DatabaseHelper dH = new DatabaseHelper(context);
			dH.addEvent(e,currUser);
		}
	}
	
	public static void addEvent(Context context, Event e, User u){
		
			
			u.addEvent(e);
			DatabaseHelper dH = new DatabaseHelper(context);
			dH.addEvent(e,u);
		
	}
	
	/**
	 * Creates and registers a new user
	 * 
	 * @param name
	 * @param eMail
	 * @param username
	 * @param password
	 */
	public static void registerUser(String name, String eMail, String username, String password)
	{
		User u = new User(name, eMail, username, password);
		currUser=u;
		users.add(currUser);
	}
	
	//For testing the ability to add users during the run
	public static void testAddUser(String name, String eMail, String username, String password)
	{
		User u = new User(name, eMail, username, password);
		users.add(u);
		
	}

	//What's the point of this?
	public static void loadMainScreen()
	{
		currUser.getName(); // CREATE A TEXT FIELD WITH THIS THING
	}
	
	/**
	 * Returns the user currently logged into the system. 
	 * 
	 * @return
	 */
	public static User getCurrUser(){
		return currUser;
	}
	
	/**
	 * Returns a boolean that determines whether this is a newUser or not
	 * 
	 * @ return
	 */
	public static boolean getNewUser(){
		return newUser;
	}
	
	/**
	 * Takes the events from toDoList and sends them up as a String Array
	 * 
	 * @return
	 */
	public static String[] getEventsStringArray()
	{
		return currUser.getToDoListStringArray();
	}
	
	/**
	 * Gets the current users events
	 * 
	 * @return le events
	 */
	public static ArrayList<Event> getToDoListEvents()
    {
            return currUser.getToDoListEvents();
    }

	/**
	 * Sets the newUser boolean to either true or false,
	 * true for a newUser, false otherwise
	 * 
	 * @param userAttribute
	 */
	public static void setNewUser(boolean userAttribute){
		newUser=userAttribute;
	}
	
	/**
	 * Sets the event to being a new event, which is added in the next step
	 * 
	 * @param e
	 */
	public static void setNewEvent(Event e){
		newEvent=e;
	}
	
	/**
	 * Returns the MCP's new event, either
	 * one that hasn't been added (and then is)
	 * or that is null
	 * 
	 * @return
	 */
	public static Event getNewEvent(){
		return newEvent;
	}
	
	/**
	 * Sets the event to being an altered event, which is added in the next step
	 * 
	 * @param e
	 */
	public static void setAlteredEvent(Event e){
		alteredEvent=e;
	}
	
	/**
	 * Returns the MCP's altered event, either
	 * one that hasn't been added (and then is)
	 * or that is null
	 * 
	 * @return
	 */
	public static Event getAlteredEvent(){
		return alteredEvent;
	}
	
	
	public static void saveAlteredEvent(Context c){
		if(alteredEvent!=null){
			MasterControlProgram.updateEvent(c, alteredEvent);
			alteredEvent=null;
		}
	}
	
	public static void setSavedContext(Context c){
		savedContext=c;
	}
	
	public static Context getSavedContext(){
		return savedContext;
	}
	
	/**
	 * Filter Events by Completion
	 * @return
	 */
	public static ArrayList<Event> filterEventsComplete()
	{
		return currUser.filterEventsComplete();
	}
	
	/**
	 * Filter Events by Incompletion
	 * @return
	 */
	public static ArrayList<Event> filterEventsIncomplete()
	{
		return currUser.filterEventsIncomplete();
	}
	
	
	/**
	 * Filter Events by a String Type
	 * @return
	 */
	public static ArrayList<Event> filterEventsType(String type)
	{
		return currUser.filterEventsType(type);
	}
	
	/**
	 * Filter Events by after the Date
	 * @return
	 */
	public static ArrayList<Event> filterEventsDateAfter(String date)
	{
		return currUser.filterEventsDateAfter(date);
	}
	
	
	/**
	 * Filter Events by before the Date 
	 * @return
	 */
	public static ArrayList<Event> filterEventsDateBefore(String date)
	{
		return currUser.filterEventsDateBefore(date);
	}
	
	/**
	 * Gets event locations
	 * 
	 * @return
	 */
	public static ArrayList<String> getLocations(){
		return currUser.getLocations();
	}
}
